#include "DirectoryMock.h"
#include "../storage/storage.h"
#include <IStorage.h>
#include <auto_ptr.h>
#include <vector>

using namespace storagemon;
using ::testing::Return;
using ::testing::_;

class StorageObjectTest : public testing::Test
{
public:
    void SetUp()
    {
        m_storage.reset(new StorageObject("data", "/home/alexey", 1));
        m_directoryMock1.reset(new mock::DirectoryObjectMock());
        m_directoryMock2.reset(new mock::DirectoryObjectMock());
    }

    void TearDown()
    {
    }

protected:
    std::auto_ptr<IStorage> m_storage;
    std::auto_ptr<mock::DirectoryObjectMock> m_directoryMock1;
    std::auto_ptr<mock::DirectoryObjectMock> m_directoryMock2;
};

TEST_F(StorageObjectTest, GetId)
{
    ASSERT_EQ(m_storage.get()->id(), 1);
}

TEST_F(StorageObjectTest, Name)
{
    ASSERT_STREQ(m_storage.get()->name(), "data");
}

TEST_F(StorageObjectTest, Path)
{
    ASSERT_STREQ(m_storage.get()->path(), "/home/alexey");
}

TEST_F(StorageObjectTest, AddDir)
{
    ASSERT_TRUE(m_storage.get()->add_dir(m_directoryMock1.get()));
    ASSERT_EQ(m_storage.get()->size(), 1);
}

TEST_F(StorageObjectTest, RemoveDir)
{
    ASSERT_TRUE(m_storage.get()->add_dir(m_directoryMock1.get()));
    EXPECT_CALL(*(m_directoryMock1.get()), id())
        .Times(1)
        .WillOnce(Return(1));
    ASSERT_TRUE(m_storage.get()->remove_dir(1));
}

TEST_F(StorageObjectTest, AddExistingDir)
{
    EXPECT_CALL(*(m_directoryMock1.get()), id())
        .Times(2)
        .WillRepeatedly(Return(1));

    EXPECT_CALL(*(m_directoryMock1.get()), parent_id())
        .Times(2)
        .WillRepeatedly(Return(1));

    EXPECT_CALL(*(m_directoryMock1.get()), name())
        .Times(2)
        .WillRepeatedly(Return("alexey"));

    EXPECT_CALL(*(m_directoryMock1.get()), path())
        .Times(2)
        .WillRepeatedly(Return("/home/alexey"));

    ASSERT_TRUE(m_storage.get()->add_dir(m_directoryMock1.get()));
    ASSERT_FALSE(m_storage.get()->add_dir(m_directoryMock1.get()));
}

TEST_F(StorageObjectTest, AddNotExistingDir)
{
    EXPECT_CALL(*(m_directoryMock1.get()), id())
        .Times(1)
        .WillRepeatedly(Return(1));

    EXPECT_CALL(*(m_directoryMock1.get()), parent_id())
        .Times(1)
        .WillRepeatedly(Return(1));

    EXPECT_CALL(*(m_directoryMock1.get()), name())
        .Times(1)
        .WillRepeatedly(Return("alexey"));

    EXPECT_CALL(*(m_directoryMock1.get()), path())
        .Times(1)
        .WillRepeatedly(Return("/home/alexey"));

    EXPECT_CALL(*(m_directoryMock2.get()), id())
        .Times(1)
        .WillRepeatedly(Return(2));

    EXPECT_CALL(*(m_directoryMock2.get()), parent_id())
        .Times(1)
        .WillRepeatedly(Return(1));

    EXPECT_CALL(*(m_directoryMock2.get()), name())
        .Times(1)
        .WillRepeatedly(Return("alexey"));

    EXPECT_CALL(*(m_directoryMock2.get()), path())
        .Times(1)
        .WillRepeatedly(Return("/home/alexey"));

    ASSERT_TRUE(m_storage.get()->add_dir(m_directoryMock1.get()));
    ASSERT_TRUE(m_storage.get()->add_dir(m_directoryMock2.get()));
}